package cn.com.franke.functional;

import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.*;
import org.junit.Test;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 函数式编程Java8里已有体现
 * Created by liuzh on 2017/5/1.
 */
public class FunctionalTest {
    //不应该随便使用函数式风格，除非你绝对确定以下两点之一：
//    ①.使用函数式风格以后，整个工程的代码行会净减少。在上面的例子中，函数式版本用了11行， 命令式代码用了6行，把函数的定义放到另一个文件或常量中，并不能帮助减少总代码行。
//    ②.为了提高效率，转换集合的结果需要懒视图，而不是明确计算过的集合。此外，确保你已经阅读和重读了Effective Java的第55条，并且除了阅读本章后面的说明，你还真正做了性能测试并且有测试数据来证明函数式版本更快。

    //    Guava提供两个基本的函数式接口：
//    Function<A, B>，它声明了单个方法B apply(A input)。
//    Predicate<T>，它声明了单个方法boolean apply(T input)。
    @Test
    public void test() {
        List<String> names = Lists.newArrayList("zhao", "wei", "cat");

//        List<Person> people = Lists.transform(names, new Function<String, Person>() {
//            @Override
//            public Person apply(String s) {
//                return new Person(s);
//            }
//        });
        Map<String, Person> personWithName = Maps.newHashMap();
        personWithName.put("zhao", new Person("zhao"));
        personWithName.put("wei", new Person("wei"));
        personWithName.put("cat", new Person("cat"));
        List<Person> people = Lists.transform(names, Functions.forMap(personWithName));
        System.out.println(people);
        ListMultimap<String, String> firstNameToLastNames = ArrayListMultimap.create();
        firstNameToLastNames.put("liu","ajs");
        firstNameToLastNames.put("zhang","ll");
        firstNameToLastNames.put("qiao","hopngwei");
// maps first names to all last names of people with that first name
        ListMultimap<String, String> firstNameToName = Multimaps.transformEntries(firstNameToLastNames,
                new Maps.EntryTransformer<String, String, String>() {
                    public String transformEntry(String firstName, String lastName) {
                        return firstName + " " + lastName;
                    }
                });
        System.out.println(firstNameToName);
    }

    class Person {
        private String name;
        private int age;
        private Date date;

        Person(String name) {
            this.name = name;
        }

        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        Person(String name, int age, Date date) {
            this.name = name;
            this.age = age;
            this.date = date;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public Date getDate() {
            return date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", date=" + date +
                    '}';
        }
    }
}
